package com.leha.forum.lehare.service.impl;

import com.leha.forum.lehare.entity.Permission;
import com.leha.forum.lehare.entity.UserRole;
import com.leha.forum.lehare.mapper.LevelDAO;
import com.leha.forum.lehare.mapper.UserLevelDAO;
import com.leha.forum.lehare.entity.UserLevel;
import com.leha.forum.lehare.exception.BusinessException;
import com.leha.forum.lehare.entity.Level;
import com.leha.forum.lehare.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@Transactional
public class LevelServiceImpl implements LevelService {

    @Autowired
    private LevelDAO levelDAO;
    @Autowired
    private UserLevelDAO userLevelDAO;
    @Autowired
    private NotificationService notificationService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private RolePermissionService rolePermissionService;
    @Autowired
    private LevelPermissionService levelPermissionService;

    @Override
    public Level createLevel(Level level) {
        // 检查等级名称是否已存在
        if (levelDAO.selectAll().stream()
                .anyMatch(l -> l.getLevelName().equals(level.getLevelName()))) {
            throw new BusinessException("等级名称已存在");
        }

        level.setCreatedAt(new Date());
        level.setUpdatedAt(new Date());
        levelDAO.insert(level);
        return level;
    }
    @Override
    public Level updateLevel(Level level) {
        Level existingLevel = getCurrentUserLevel(level.getLevelId());

        // 更新字段
        existingLevel.setLevelName(level.getLevelName());
        existingLevel.setPostCount(level.getPostCount());
        existingLevel.setReplyCount(level.getReplyCount());
        existingLevel.setEssenceCount(level.getEssenceCount());
        existingLevel.setMinExperience(level.getMinExperience());
        existingLevel.setUpdatedAt(new Date());

        levelDAO.update(existingLevel);
        return existingLevel;
    }

    @Override
    public Level getUserLevelInfo(Integer userId) {
        UserLevel userLevel = userLevelDAO.selectByUserId(userId);
        if (userLevel == null) {
            throw new BusinessException("用户等级信息不存在");
        }
        return levelDAO.selectLevelById(userLevel.getLevelId());
        /*//        Level level=levelDAO.selectLevelById()
        Level level = levelDAO.selectLevelById(userLevel.getLevelId());

        Level info = new Level();
        info.setLevelName(level.getLevelName());
        info.setTitle(level.getTitle());
        info.setIconUrl(level.getIconUrl());
//        info.setExperience(userLevel.getExperience());

        return info;
//        return userLevelDAO.selectByUserIdWithLevel(userId);*/
    }

    @Override
    public List<Level> getAllLevels() {
        return levelDAO.selectAll();
    }
    @Override
    @Transactional
    public void addUserExperience(Integer userId, Integer points) {
// 1. 获取用户的等级关联记录（操作的是UserLevel表）
        UserLevel userLevel = userLevelDAO.selectByUserId(userId);

        if (userLevel == null) {
            // 初始化用户等级记录（UserLevel）
            userLevel = new UserLevel();
            userLevel.setUserId(userId);
            userLevel.setLevelId(1); // 默认1级
            userLevel.setExperience(0);
            userLevelDAO.insert(userLevel);
        }

        // 2. 增加经验值（操作UserLevel的experience字段）
        userLevel.addExperience(points);

        // 3. 检查是否升级（查询Level表判断是否满足下一级条件）
        Level nextLevel = levelDAO.selectNextLevel(userLevel.getExperience());
        if (nextLevel != null) {
            // 更新UserLevel中的levelId
            userLevel.setLevelId(nextLevel.getLevelId());

            // 发送站内通知
            notificationService.sendNotification(Long.valueOf(userId), "等级已提升至 " + nextLevel.getLevelName());

            // 获取该等级解锁的权限
            List<Permission> levelPermissions = levelPermissionService.getLevelPermissions(nextLevel.getLevelId());

            // 给用户添加权限
            List<UserRole> userRoles = userRoleService.getUserRoles(Long.valueOf(userId));
            if (!userRoles.isEmpty()) {
                Integer roleId = userRoles.get(0).getRoleId();
                for (Permission levelPermission : levelPermissions) {
                    rolePermissionService.bindPermission(roleId, levelPermission.getPermissionId());
                }
            }
        }

        // 4. 更新UserLevel记录
        userLevelDAO.update(userLevel);
    }

    @Override
    public Level getCurrentUserLevel(Integer userId) {
        UserLevel userLevel = userLevelDAO.selectByUserId(userId);
        if (userLevel == null) {
            throw new BusinessException("用户等级信息不存在");
        }
        return levelDAO.selectLevelById(userLevel.getLevelId());
    }
/*
        userLevelDAO.addExperience(userId, points, new Date());

       // 检查是否需要升级
        UserLevel userLevel = userLevelDAO.selectByUserId(userId);
        List<Level> appropriateLevels = levelService.getLevelsByExperience(userLevel.getExperience());
        if (!appropriateLevels.isEmpty() &&
                !Objects.equals(appropriateLevels.get(0).getLevelId(), userLevel.getLevelId()))  {
            userLevelDAO.updateLevelId(userLevel.getUserLevelId(),
                    appropriateLevels.get(0).getLevelId(),
                    new Date());
        }*/


    @Override
    public void deleteLevel(Integer levelId) {
        // 检查是否有用户关联此等级
        // 实际项目中应该有更完善的检查逻辑
        levelDAO.deleteLevelById(levelId);
    }
    @Override
    public List<Level> getLevelsByExperience(Integer experience) {
        return levelDAO.selectByExperience(experience);
    }

/*    // LevelServiceImpl实现类添加方法
    @Override
    public void setPromotionConditions(Integer levelId, Integer postCount, Integer replyCount, Integer essenceCount, Integer minExperience) {
        Level level = getLevelById(levelId);
        level.setPostCount(postCount);
        level.setReplyCount(replyCount);
        level.setEssenceCount(essenceCount);
        level.setMinExperience(minExperience);
        level.setUpdatedAt(new Date());
        levelDAO.updateLevel(level);
    }*/
}